package io.renren.service.impl;

import io.renren.common.exception.RRException;
import io.renren.common.utils.ConfigConstant;
import io.renren.common.utils.HttpContextUtils;
import io.renren.common.utils.IPUtils;
import io.renren.common.utils.ProjectConstant;
import io.renren.common.validator.Assert;
import io.renren.dao.MemberDao;
import io.renren.entity.BalanceDetailEntity;
import io.renren.entity.MemberEntity;
import io.renren.entity.SysOssEntity;
import io.renren.entity.TeamEntity;
import io.renren.entity.TokenEntity;
import io.renren.form.PhoneCodeForm;
import io.renren.form.RegisterForm;
import io.renren.service.BalanceDetailService;
import io.renren.service.MemberService;
import io.renren.service.RecDownloadService;
import io.renren.service.SysConfigService;
import io.renren.service.SysOssService;
import io.renren.service.TeamService;
import io.renren.service.TokenService;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;

@Service("memberService")
public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService {

	@Autowired
	TokenService tokenService;

	@Autowired
	TeamService teamService;

	@Autowired
	SysConfigService sysConfigService;

	@Autowired
	SysOssService sysOssService;

	@Autowired
	RecDownloadService recDownloadService;

	@Autowired
	BalanceDetailService balanceDetailService;

	@Override
	public Map<String, Object> login(MemberEntity member) {

		Assert.notNull(member, "登录失败");

		// 账号状态
		if (member.getStatus() == ProjectConstant.COMMON_STATUS_DISABLE) {
			throw new RRException("账号被禁用");
		}

		// 获取登录token
		TokenEntity tokenEntity = tokenService.createToken(member.getId());

		Map<String, Object> map = new HashMap<>(2);
		map.put("token", tokenEntity.getToken());
		map.put("expire", tokenEntity.getExpireTime().getTime());

		return map;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void save(RegisterForm form) {
		MemberEntity member = new MemberEntity();
		if (StringUtils.isNotBlank(form.getOpenid())) {
			member.setOpenid(form.getOpenid());
		} else {
			member.setMobile(form.getMobile());
		}
		Date now = new Date();
		member.setNickname(form.getNickname());
		member.setHeadImg(form.getHeadImg());
		member.setCode(genCode());
		member.setRegIp(IPUtils.getIpAddr(HttpContextUtils.getHttpServletRequest()));
		member.setCreateTime(now);
		member.setLastLoginTime(now);
		// 注册送红包
		if (sysConfigService.getValueI(ConfigConstant.REG_REWARD_PACKET) == ProjectConstant.COMMON_YES) {
			member.setBalance(sysConfigService.getValueD(ConfigConstant.REG_REWARD_AMOUNT));
			member.setWithdrawAmountLimit(member.getBalance());
			this.insert(member);

			BalanceDetailEntity detail = new BalanceDetailEntity();
			detail.setMemberId(member.getId());
			detail.setBalanceChange(member.getBalance());
			detail.setType(ProjectConstant.ORDER_TYPE_PRIZE);
			detail.setDescription("注册奖励");
			detail.setCreateTime(now);
			balanceDetailService.insert(detail);
		} else {
			this.insert(member);
		}

	}

	private String genCode() {
		String code = RandomStringUtils.randomAlphanumeric(6).toUpperCase();
		if (this.selectCount(new EntityWrapper<MemberEntity>().eq("code", code)) > 0) {
			return genCode();
		}
		return code;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateImage(Long id, int type, String url) {

		MemberEntity member = selectById(id);
		member.setUpdateTime(new Date());

		switch (type) {
		case ProjectConstant.UPLOAD_TYPE_ALIPAY:

			Assert.isNull(member.getAlipay(), "禁止修改信息");
			if (StringUtils.isNotBlank(member.getAlipayImg())) {
				SysOssEntity oss = sysOssService.selectOne(new EntityWrapper<SysOssEntity>().eq("url", member.getAlipayImg()));
				if (oss != null) {
					oss.setFlag(ProjectConstant.COMMON_YES);
					sysOssService.updateById(oss);
				}
			}
			member.setAlipayImg(url);
			break;
		case ProjectConstant.UPLOAD_TYPE_WECHAT:

			Assert.isNull(member.getWechat(), "禁止修改信息");
			if (StringUtils.isNotBlank(member.getWechatImg())) {
				SysOssEntity oss = sysOssService.selectOne(new EntityWrapper<SysOssEntity>().eq("url", member.getWechatImg()));
				if (oss != null) {
					oss.setFlag(ProjectConstant.COMMON_YES);
					sysOssService.updateById(oss);
				}
			}
			member.setWechatImg(url);
			break;
		default:
			throw new RRException("参数错误");
		}

		Assert.isTrue(this.updateById(member), "系统繁忙");
	}

	@Override
	public void bindMobile(MemberEntity member, PhoneCodeForm form) {
		// 推荐人必填
		if (sysConfigService.getValueI(ConfigConstant.MUST_REC_PERSON) == ProjectConstant.COMMON_YES) {
			Assert.hasText(form.getRecPerson(), "邀请码不能为空");
		}
		Date now = new Date();

		// 手机号验证
		Assert.isTrue(this.selectCount(new EntityWrapper<MemberEntity>().eq("mobile", form.getMobile())) == 0, "手机号已注册");

		// 查询推荐人
		if (StringUtils.isNotBlank(form.getRecPerson())) {
			// 处理上级推荐人
			MemberEntity m = this.selectOne(new EntityWrapper<MemberEntity>().eq("status", ProjectConstant.COMMON_STATUS_ENABLE).eq("code", form.getRecPerson()));
			Assert.notNull(m, "邀请码无效");
			TeamEntity teamEntity = new TeamEntity();
			teamEntity.setMemberId(member.getId());
			teamEntity.setHigherOne(m.getId());
			TeamEntity t = teamService.selectOne(new EntityWrapper<TeamEntity>().eq("member_id", m.getId()));
			if (t != null) {
				if (t.getHigherOne() != null) {
					teamEntity.setHigherTwo(t.getHigherOne());
					if (t.getHigherTwo() != null) {
						teamEntity.setHigherThree(t.getHigherTwo());
					}
				}
			}
			teamService.insert(teamEntity);

			member.setRecPerson(form.getRecPerson());
			recDownloadService.deleteById(form.getMobile());
		}

		member.setMobile(form.getMobile());
		member.setUpdateTime(now);
		Assert.isTrue(this.updateById(member), "系统繁忙");
	}
}
